; 用户程序
;-----------------
; 程序头部
;-----------------
SECTION header vstart=0
    program_length dd program_end

    head_length dd header_end   ; 头部长度
    
    stack_seg dd 0   ; 用于接收堆栈段选择子
    stack_len dd 1   ; 程序建议的堆栈大小，以 4KB 为单位

    program_entry dd start ; 程序入口
    code_seg dd section.code.start
    code_len dd code_end

    data_seg dd section.data.start
    data_len dd data_end
;-------------------------
; 符号地址索引
;-------------------------
salt_items dd (header_end-salt)/256
salt:
    PrintString dd '@PrintString'
        times 256-($-PrintString) db 0
    TerminateProgram db '@TerminateProgram'
        times 256-($-TerminateProgram) db 0
    ReadDiskData db '@ReadDiskData'
        times 256-($-ReadDiskData) db 0
    ConvertLinearToPhysical db '@ConvertLinearToPhysical'
        times 256-($-ConvertLinearToPhysical) db 0
header_end:
;--------------------------
; 数据段
;--------------------------
SECTION data vstart=0
    buffer times 1024 db 0  ; 缓冲区
    message_1         db  0x0d,0x0a,0x0d,0x0a
                      db  '**********User program is runing**********'
                      db  0x0d,0x0a,0
    message_2         db  '  Disk data:',0x0d,0x0a,0
data_end:
;============================
[bits 32]
;============================
SECTION code vstart=0
start:
         mov eax,ds
         mov fs,eax
     
         mov eax,[stack_seg]
         mov ss,eax
         mov esp,0
     
         mov eax,[data_seg]
         mov ds,eax
     
         mov ebx,message_1
         call far [fs:PrintString]
     
         mov eax,79                         ;逻辑扇区号80
         mov ebx,buffer                      ;缓冲区偏移地址
         mov edx,1
         call far [fs:ConvertLinearToPhysical]     ;将线性地址转换为物理地址
         call far [fs:ReadDiskData]          ;段间调用
     
         mov ebx,message_2
         call far [fs:PrintString]
     
         mov ebx,buffer 
         call far [fs:PrintString]           ;too.
     
         jmp far [fs:TerminateProgram]       ;将控制权返回到系统 
code_end:
SECTION trailer
program_end: